﻿#include "core/CPU.h"

#include <core/Enum.h>
#include <Common.h>

//aarch64
#include "arch/arm64/ARM64Decoder.h"
#include <arch/arm64/Arm64.h>

#define TAG "CPU"

#define HOME_PATH	"G:\\admin\\bobokan\\simulator\\ardlator\\exam\\u-boot.bin"

#define COM_PATH	"D:\\teamwork\\xiaoyu\\bobokan\\simulator\\ardlator\\exam\\u-boot.bin"

void CPU::init(CPUArch _arch)
{
	LogD("exist arch:" << printEnum(_arch));
	auto f = fopen_s(&_firmware, COM_PATH, "rb");
	if (f) {
		Abort("can\'t open firmware");
	}
	switch (_arch)
	{
	case CPUArch::Arm64:
		_arm64Init();
		break;
	case CPUArch::Mcu51:
	case CPUArch::Arm:
	case CPUArch::RiscV:
	case CPUArch::x86:
	default:
		Abort("can\'t exist arch"<< printEnum(_arch));
		break;
	}
}

int CPU::exec()
{
	uint64_t pc = decoder->getPC();
	try
	{
		uint64_t code = 0;
		if (_code.find(pc) == _code.end()) {
			
			uint32_t data[READOPPER] = {0};
			fseek(_firmware, pc, SEEK_SET);
			//数据的存储位置 目标缓冲区的大小（以字节为单位）要读取的项的大小（以字节为单位） 要读取的项的最大数量 ->已读取到缓冲区中的（整数）项数
			auto count = fread_s(data, READOPPER * sizeof(uint32_t), sizeof(uint32_t), READOPPER, _firmware);
			if (count > 0) {
				for (size_t i = 0; i < count; i++)
				{
					_code[pc + i * 4] = data[i];
					//LogD("-->" << i << ":" << std::hex<< std::setw(8) << std::setfill('0') << _code[pc + i]);
				}
			}
			else {
				throw "read no data";
			}
		}
		decoder->decoder(_code[pc]);
	}
	catch (const std::exception& e)
	{
		Abort("can\'t get PC code:" << pc << ":->" << e.what());
	}

    return 0;
}

void CPU::interruptHandle()
{
}

CPU::~CPU()
{
	if (_firmware) {
		fclose(_firmware);
		_firmware = nullptr;
	}
}

void CPU::_arm64Init()
{
	decoder  = std::make_unique<ARM64Decoder>();
}
